//file:login.js
// test thread

background = Components.classes["@mozilla.org/thread-manager;1"].getService().newThread(0);
main = Components.classes["@mozilla.org/thread-manager;1"].getService().mainThread;
var socket_id = 0;
var recv_flag = false ;
var recv_msg="";

//########################################################################################
// the FooCallback and Foo . an example of threading in GECKO 1.9 , use hello() to test it.
//##########################################################################################

var FooCallback = function ( id ,result ){
    this.id = id ;
    this.result = result ;
};

FooCallback.prototype = {
    run : function (){
          try{
                //this is where we can work with the main thread after the job.
                document.getElementById("lbl_time").value=this.result;

          }catch(err){
              Components.utils.reportError(err);
          }
      },
    QueryInterface: function (iid){
                    if(iid.equals(Components.interfaces.nsIRunnable) || iid.equals(Components.interfaces.nsISupports)){
                            return this;
                    }
                    throw Components.results.NS_REEOR_NO_INTERFACE;
                }
};

var Foo = function(id,result){
    this.id = id ;
    this.result = result ;
};
Foo.prototype = {
    run : function(){
              try {
                    //Callback to the main thread
                    main.dispatch(new FooCallback(this.id ,this.result) , background.DISPATCH_NORMAL);
              }catch(err){
                  Components.utils.reportError(err);
              }
          },
            QueryInterface: function(iid){
                    if (iid.equals(Components.interfaces.nsIRunnable) || iid.equals(Components.interfaces.nsISupports)){
                        return this;
                    }
                    throw Components.results.NS_REEOR_NO_INTERFACE;
                }
};
function hello(){
    now = new Date();
    result = now.getHours()+":" + now.getMinutes() + ":" + now.getSeconds();
    background.dispatch(new Foo("id0",result) , background.DISPATCH_NORMAL);
    setTimeout("hello()",1000);
};
//#################################################
// A test of Javascript
//################################################
function hellobak(){
    var fetionno = document.getElementById("user_account").value;
    var pswd = document.getElementById("user_pswd").value;
    alert("fetionno:" + fetionno + "pswd" + pswd );
}


//#################################################
// A test of MyComponents 
// when the login return is ok ,then open the mainWin.
//#################################################

function openMain(res){
    var fetionon = document.getElementById("user_account").value;
    window.openDialog("main.xul","XYG","local,width=300,height=600",self,fetionon,res);
    window.close();

}

//#################################################
// Login to MainWin
// register to Fetino Server.
//#################################################
function login(){
    document.getElementById("lbl_tip").value="";
    var obj = Components.classes["@mozilla.org/fetion/fetionCom;1"].getService();
    obj = obj.QueryInterface(Components.interfaces.IFetionCom);
    
    var fetionno = document.getElementById("user_account").value;
    var pswd = document.getElementById("user_pswd").value;
    
    alert("start to login");
    res = obj.Login(fetionno , pswd ); //the Login function returns the socket ID .
    
    if(res>=0)
    {
        alert("login successful!");
        openMain(res);
    }else{
        document.getElementById("lbl_tip").value="wrong account or password .";
    }
}
//end of login.js
//
//
//################################################                                                              
//// CB_updateUI is a callback function used by updateUI
//################################################


var CB_updateUI = function (id , value){ 
    this.id=id;
    this.value= value;
};



CB_updateUI.prototype = {
                run : function (){
                          try {
                              document.getElementById(this.id).value=document.getElementById(this.id).value+this.value ;
                          }catch(err){
                              Components.utils.reportError(err);
                          }
                      },
                QueryInterface: function (iid) {
                    if(iid.equals(Components.interfaces.nsIRunnable) || iid.equals(Components.interfaces.nsISupports)){
                        return this;
                    }
                    throw Components.result.NS_REEOR_NO_INTERFACE;
                }
};
                      
var updateUI = function (id , value){
    this.id=id;
    this.value=value;
}
updateUI:prototype = {
    run : function (){
          try{
                //this is where we can work with the main thread after the job.
                //document.getElementById("lbl_time").value=this.result;
                main.dispatch(new CB_updateUI(this.id, this.value) , background.DISPATCH_NORMAL);
          }catch(err){
              Components.utils.reportError(err);
          }
      },
    QueryInterface: function (iid){
                    if(iid.equals(Components.interfaces.nsIRunnable) || iid.equals(Components.interfaces.nsISupports)){
                            return this;
                    }
                    throw Components.results.NS_REEOR_NO_INTERFACE;
                }
};

var aKeepListen = function (s_id) {
    this.id = s_id ; 
    alert("a keep listen called by the bgThread");
    //why only once ?
}
aKeepListen:prototype = {
    run : function (){
              try {
                    a_listen(this.id);
                    //document.getElementById("box_msg").value = document.getElementById("box_msg").value +  this.value ;
                    // the above line will not act unless it is called by the main UI thread.
              }catch(err){
                  Components.utils.reportError(err);
              }
      },
    QueryInterface: function (iid){
                    if(iid.equals(Components.interfaces.nsIRunnable) || iid.equals(Components.interfaces.nsISupports)){
                            return this;
                    }
                    throw Components.results.NS_REEOR_NO_INTERFACE;
                }
};

//########################################################################
//Init Related Functions. 
//########################################################################

function  a_listen(s_id){//s_id is short for socket_id;
    this.s_id=s_id;    
    var obj = Components.classes["@mozilla.org/fetion/fetionCom;1"].getService();
    obj = obj.QueryInterface(Components.interfaces.IFetionCom);
    
    var len = 0;
    len = obj.GetMsg(); //to recieve the msg from the socket ,
                        //will blocked until the data is aviable.
    if(len > 0 ){                    
        recv_flag=true; // this var is no longer need. will be removed.
    }
};
function createSocket(){
    var obj = Components.classes["@mozilla.org/fetion/fetionCom;1"].getService();
    obj = obj.QueryInterface(Components.interfaces.IFetionCom);
    socket_id = obj.CreateSocket();
};
function keepListen(){
    //here the main thread will be blocked. any good ideals? to set the loop to the child thread?
    //because the updateUI event is dispatched to the background thread.so it will never 
    //block the main thread.. so here is ok. this line can be called anywhere and will likely be used
    //inside a loop to push a lot of compute-intensive work onto the background thread .allowing the 
    //UI thread to remain responsive ...
    // use while loop , when read from the blocking socket ,if there is no data aviable ,it will wait for a msg.
    // !!!!!!!!!!!!! but the  a_listen(x) will blocked!!!!!!!!!!!!!!!
    
    if(recv_flag){
        background.dispatch(new updateUI("box_msg" , "test--") , background.DISPATCH_NORMAL);//callback to updateUI
    }
    //setTimeOut("keepListen()",1000);  //about 0.1 second a loop .
};

function startListen(){
    //while(true){
    alert("start listening --");
    background.dispatch(new aKeepListen(socket_id) , background.DISPATCH_NORMAL);
    setTimeout("startListen()" , 1000);  //how do i know this line will act ?
}
function register(){
    alert("register -- " );
};

function init(){
    createSocket() ;//if socket is created , the id is > 0.
    document.getElementById('box_msg').value=socket_id;
    if (socket_id > 0 ) //validate the socket id
    {
        startListen();
        alert("start ");
        keepListen(); //error:  no responding here ########$#$#%#@%@$#^%@$^&@^@#$&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%^
        alert("here");
        login();
    }
};

//########################################################################################
// test of the proxyObject to mainplate the multiThread.  
//##########################################################################################
function proxyInit(){
    //connect the xpcom 
    //get the obj  of components.
    //run the com's testProxyThread
    //print to the terminal as stderr
    //i
}

function testProxyThread(){
    proxyInit();
}



